home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / prog_c / cuj0696.zip / DWYER.ZIP / COLISION.TST / CLSNDATA.C next >
C/C++ Source or Header  |  1996-03-26  |  4KB  |  142 lines

  1. /* ============ */
  2. /* ClsnData.c    */
  3. /* ============ */
  4. #include <clsndefs.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <assert.h>
  8.  
  9. #define    FULL_SIZE    ((unsigned)RAND_MAX+1U)
  10. ULONG    ChkBits[FULL_SIZE];
  11.  
  12. static
  13. UCHAR    bit_mask[] = {    1 << 7, 1 << 6, 1 << 5, 1 << 4,
  14.             1 << 3, 1 << 2, 1 << 1, 1
  15.              };
  16. /* INDENT ON */
  17. /* ==================================================== */
  18. /* LinTrp - Interpolates X0 Linearly in [X1,Y1],[X2,Y2] */
  19. /* ==================================================== */
  20. static double
  21. LinTrp(double X0, double X1, double Y1, double X2, double Y2)
  22. {
  23.     return (X1 == X2) ? Y1 : Y1 + (Y2 - Y1) / (X2 - X1) * (X0 - X1);
  24. }
  25. /* ==================================================================== */
  26. /* SetBit - sets bit at bit_posn in bit_ary to bit_val         */
  27. /* ==================================================================== */
  28. static    void
  29. SetBit(UCHAR *bit_ary, ULONG bit_posn, UCHAR bit_val)
  30. {
  31.     if (bit_val)            /* set the bit */
  32.     {
  33.     bit_ary[bit_posn >> 3] |= bit_mask[bit_posn & 0x07];
  34.     }
  35.     else                /* clear the bit */
  36.     {
  37.     bit_ary[bit_posn >> 3] &= ~bit_mask[bit_posn & 0x07];
  38.     }
  39. }
  40. /* ==================================================================== */
  41. /* TestBit = returns 1 if bit at bit_posn in bit_ary is a 1, else 0    */
  42. /* ==================================================================== */
  43. static    UCHAR
  44. TestBit(UCHAR *bit_ary, ULONG bit_posn)
  45. {
  46.     return((UCHAR)(bit_ary[bit_posn >> 3] & bit_mask[bit_posn & 0x07]));
  47. }
  48. /* ==================================================================== */
  49. /* GetBitVector - Returns a bit vector of observations from RandFun()    */
  50. /* ==================================================================== */
  51. static    ULONG
  52. GetBitVector(CLSN_DATA_STRU *ClsnData)
  53. {
  54.     int     k;
  55.     ULONG   BitVector = 0;
  56.     ULONG   Next;
  57.  
  58.     for (k = 1; k <= ClsnData->NumParts; ++k)
  59.     {
  60.     Next = (ULONG)(ClsnData->RandFun() & ClsnData->BitMask);
  61.     BitVector = (BitVector << ClsnData->NumBits) | Next;
  62.     }
  63.  
  64.     ClsnData->NumVariates += ClsnData->NumParts;
  65.  
  66.     return (BitVector);
  67. }
  68. /* ==================================================================== */
  69. /* TerpHitProb - Interpolates in Probability Table for NumHits        */
  70. /* ==================================================================== */
  71. static    void
  72. TerpHitProb(CLSN_DATA_STRU *ClsnData)
  73. {
  74.     int     k;
  75.     double  X0, Y0, X1, Y1, X2, Y2;
  76.  
  77.     for (k = TMAX - 2; k >= 0; --k)
  78.     {
  79.     if (ClsnData->NumHits < ClsnData->ClsnStats[k])
  80.     {
  81.         break;
  82.     }
  83.     }
  84.  
  85.     if (k < 0)
  86.     {
  87.     ClsnData->HitProb = 1.0;
  88.     }
  89.     else if (ClsnData->NumHits == 0)
  90.     {
  91.     ClsnData->HitProb = 0.0;
  92.     }
  93.     else
  94.     {
  95.     X1 = (double)ClsnData->ClsnStats[k];
  96.     Y1 = ClsnData->ClsnProbs[k];
  97.     X2 = (double)ClsnData->ClsnStats[k+1];
  98.     Y2 = ClsnData->ClsnProbs[k+1];
  99.  
  100.     X0 = (double)ClsnData->NumHits;
  101.     Y0 = LinTrp(X0, X1, Y1, X2, Y2);
  102.  
  103.     ClsnData->HitProb = Y0;
  104.     }
  105. }
  106. /* ==================================================================== */
  107. /* GetCollisionData - Records Number of Collisions in M urns of N balls    */
  108. /* ==================================================================== */
  109. void
  110. GetCollisionData(CLSN_DATA_STRU *ClsnData)
  111. {
  112.     UINT    k;
  113.     ULONG   BitVctr;
  114.     UINT    ClsnCt = 0;
  115.  
  116.     for (k = 0; k < FULL_SIZE; ++k)
  117.     {
  118.     ChkBits[k] = 0;
  119.     }
  120.     for (k = 0; k < ClsnData->NumObs; ++k)
  121.     {
  122.     BitVctr = GetBitVector(ClsnData);
  123.  
  124.     assert(BitVctr < (ULONG)ClsnData->NumCategories);
  125.  
  126.     if (TestBit((UCHAR *)ChkBits, BitVctr) == 0)
  127.     {
  128.         SetBit((UCHAR *)ChkBits, BitVctr, 1);
  129.     }
  130.     else
  131.     {
  132.         ++ClsnCt;
  133.     }
  134.     }
  135.  
  136.     /* ----------------------------------------------- */
  137.     /* Store Collision Count & Interpolate Probability */
  138.     /* ----------------------------------------------- */
  139.     ClsnData->NumHits = ClsnCt;
  140.     TerpHitProb(ClsnData);
  141. }
  142.